﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Numbers.Arithmatic;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace Numbers
{
    /// <summary>
    /// A fairly simple tag efficiency class - just holds onto the 
    /// efficiency for all three types of quarks - l, c, and bottom.
    /// </summary>
    public class TagEfficiency : INotifyPropertyChanged
    {
        internal Value _eff_b = new Value() { MaxValue = 1.0, MinValue = 0.0 };
        internal Value _eff_c = new Value() { MaxValue = 1.0, MinValue = 0.0 };
        internal Value _eff_l = new Value() { MaxValue = 1.0, MinValue = 0.0 };

        public Value eff_bValue
        {
            get { return _eff_b; }
        }
        public Value eff_cValue
        {
            get { return _eff_c; }
        }
        public Value eff_lValue
        {
            get { return _eff_l; }
        }

        /// <summary>
        /// Get/Set the light quark efficiency.
        /// </summary>
        public double eff_b { get { return _eff_b.Val; } set { ChangeValue(ref _eff_b, value, "eff_b"); } }

        /// <summary>
        /// Get/Set the light quark efficiency.
        /// </summary>
        public double eff_c { get { return _eff_c.Val; } set { ChangeValue(ref _eff_c, value, "eff_c"); } }

        /// <summary>
        /// Get/Set the light quark efficiency.
        /// </summary>
        public double eff_l { get { return _eff_l.Val; } set { ChangeValue(ref _eff_l, value, "eff_l"); } }

        public TagEfficiency()
        {
            ///
            /// Forward the changes to the properties.
            ///

            _eff_b.PropertyChanged += new PropertyChangedEventHandler((o, e) => { OnPropertyChanged("eff_b"); });
            _eff_c.PropertyChanged += new PropertyChangedEventHandler((o, e) => { OnPropertyChanged("eff_c"); });
            _eff_l.PropertyChanged += new PropertyChangedEventHandler((o, e) => { OnPropertyChanged("eff_l"); });

            ///
            /// Setup the tracking collection (makes display in plots simpler)
            /// 

            EffArray = new ObservableCollection<ValueTracker>();
            EffArray.Add(new ValueTracker(_eff_l) { Name = "l" });
            EffArray.Add(new ValueTracker(_eff_c) { Name = "c" });
            EffArray.Add(new ValueTracker(_eff_b) { Name = "b" });
        }

        /// <summary>
        /// We are changing a property directly. Check to see if the number actually changed,
        /// and fire any events that are required.
        /// </summary>
        /// <param name="p"></param>
        /// <param name="value"></param>
        /// <param name="p_2"></param>
        private void ChangeValue(ref Value current, double newValue, string propName)
        {
            if (current.Val != newValue)
            {
                current.Val = newValue;
                OnPropertyChanged(propName);
            }
        }

        /// <summary>
        /// Fire the event, if anyone is listening!
        /// </summary>
        /// <param name="propName"></param>
        private void OnPropertyChanged(string propName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }

        /// <summary>
        /// Generate multiplication by an alpha!
        /// </summary>
        /// <param name="eff_LT_p"></param>
        /// <param name="alpha_LT_p_n"></param>
        /// <param name="eff_LT_n"></param>
        public static void Multiply(TagEfficiency result, Alpha a, TagEfficiency source)
        {
            Multiplication.Create(new Operand(result._eff_b, true),
                new Operand[] {
                    new Operand(a._alpha_b),
                    new Operand(source._eff_b, true)
                });
            Multiplication.Create(new Operand(result._eff_c, true),
                new Operand[] {
                    new Operand(a._alpha_c),
                    new Operand(source._eff_c, true)
                });
            Multiplication.Create(new Operand(result._eff_l, true),
                new Operand[] {
                    new Operand(a._alpha_l),
                    new Operand(source._eff_l, true)
                });
        }

        /// <summary>
        /// Generate multipley by two eff and an alpha!
        /// </summary>
        /// <param name="eff_LTSMT_n"></param>
        /// <param name="alpha_doubleTag"></param>
        /// <param name="eff_LT_n"></param>
        /// <param name="eff_SMT_n"></param>
        public static void Multiply(TagEfficiency result, Alpha a, TagEfficiency source1, TagEfficiency source2)
        {
            Multiplication.Create(new Operand(result._eff_b, true),
                new Operand[] {
                    new Operand(a._alpha_b),
                    new Operand(source1._eff_b, true),
                    new Operand(source2._eff_b, true)
                });
            Multiplication.Create(new Operand(result._eff_c, true),
                new Operand[] {
                    new Operand(a._alpha_c),
                    new Operand(source1._eff_c, true),
                    new Operand(source2._eff_c, true)
                });
            Multiplication.Create(new Operand(result._eff_l, true),
                new Operand[] {
                    new Operand(a._alpha_l),
                    new Operand(source1._eff_l, true),
                    new Operand(source2._eff_l, true)
                });
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        public ObservableCollection<ValueTracker> EffArray { get; set; }
    }
}
